package cn.itsource.org.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.PageBean;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartmentMapper;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService {

    @Autowired
    DepartmentMapper mapper;

    @Autowired
    RedisTemplate redisTemplate;

     /*
        将部门的层级路径整理进去
          假设去添加  /2/5/自己的id    添加时不知道自己的id   需要完成添加 返回自增id
          第一步： 选择自己的上级部门  假设 /2/5
          第二步： 将/2/5作为dirPath提交给服务器
          第三步： 服务端完成添加   将/2/5作为dirPath添加到数据库    但是dirPath缺少自己的id    返回自增id   假设是67
          第四步： 拿到自增id67    将它拼接到之前的/2/5/67
          第五步： 发起修改  67   /2/5/67

           假设去修改
           第一步： 选择自己的上级部门  假设 /2/5
           第二步： 将/2/5作为dirPath提交给服务器   同时携带了id
           第三步： 服务端拿到dirPath  拼接自己的id  /2/5/67
           第四步： 发起修改

           重写父类的add方法和update方法
         */

    @Override
    public boolean add(Department department) {
        super.add(department);
        //完成添加之后department身上有了自增的id
       return this.update(department);
    }

    @Override
    public boolean update(Department department) {
        //拿到dirPath  拼接自己的id -----》 /2/5/67
        department.setDirPath(department.getDirPath()+"/"+department.getId());
        return super.update(department);
    }

    /**
     * 从IDepartmentService实现过来的  是部门模块特有的方法
     * @param id
     * @return
     */
    @Override
    public List<Department> queryByParentId(Long id) {
        return mapper.queryByParentId(id);
    }

    /**
     * 无限级树查询实现
     * 请求获取时
     *   先从缓存中尝试获取
     *   如果拿到就返回
     *   如果拿不到   查询并封装   放入
     * @return
     */
    @Override
    public List<Department> tree() {
        //最终要返回的部门集合
        List<Department> firstDeptList = (List<Department>)redisTemplate.opsForValue().get("tree");

        if(firstDeptList == null) {

            // 1、查询所有部门  all
            List<Department> all = mapper.queryAll();

//            Map<Long, Department> collect = all.stream().collect(Collectors.toMap(department -> department.getId(), department -> department));

            //2、转成一个map结构   key 部门id   value 部门对象
            Map<Long, Department> map = new HashMap<>();
            for (Department dept : all) {
                map.put(dept.getId(), dept);
            }

            //3、遍历所有部门
            //           如果是一级部门  添加到最终返回的集合中
            //           如果有父级部门  找自己的父级部门 parent_id  将自己放入父级部门对象的children集合中

            //构建最终要返回的集合
            firstDeptList = new ArrayList<>();
            for (Department currentDept : all) {
                //判断通过  就是一级部门
                if (currentDept.getParent_id() == null) {
                    firstDeptList.add(currentDept);
                } else {
                    //得到自己的父部门id
                    Long pid = currentDept.getParent_id();
                    //用父部门id去找到父部门对象
                    Department parentDept = map.get(pid);
                    //将自己加入父级部门的children集合中
                    parentDept.getChildren().add(currentDept);
                }
            }

            //将查询并封装好的tree放入redis
            redisTemplate.opsForValue().set("tree",firstDeptList);

        }

        return firstDeptList;
    }
}
